<?php
/**
 * This class represent a user in the system.
 * The corresponding table in the database is "cb_users",
 * represented by Application_Model_UsersTable.
 * @package fr.ec-lyon.aeecl.codebar.application.model
 * @subpackage user
 * @author Théo Chamley
 */

class Application_Model_User {

	protected static $_dbTable;
	protected static $_dbTableClass = 'Application_Model_UsersTable';
	public $login;
	public $nom;
	public $prenom;
	public $promo;
	public $solde;
	protected $mdp;
	protected $id_carte;
	public $connected = false;
	protected $groupes;//groupes auquel appartient l'user
	protected $groupeActif;//groupe utilise actuellement par l'user
	protected $roles;//roles de l'user

	/**
	 *
	 * Set the table name for Application_Model_User
	 * @param String $dbTable the name of the class representing the table
	 * @throws Exception
	 */
	public static function setDbTable($dbTable) {
		if (is_string($dbTable)) {
			$dbTable = new $dbTable();
		}
		if (!$dbTable instanceof Zend_Db_Table_Abstract) {
			throw new Exception('Invalid table data gateway provided');
		}
		self::$_dbTable = $dbTable;
	}

	/**
	 *
	 * Get the table of the data base.
	 * @return the table of the database.
	 */
	public static function getDbTable() {
		if (null === self::$_dbTable) {
			self::setDbTable(self::$_dbTableClass);
		}
		return self::$_dbTable;
	}

	public function Application_Model_User($login = '',$mdp = '',$nom = '',$prenom = '',$promo = '')
	{
		$this->login = $login;
		if($mdp != '')
		{
			$this->mdp = md5($mdp);
		}
		$this->nom = $nom;
		$this->prenom = $prenom;
		$this->promo = $promo;
	}

	public function setLogin($login)
	{
		$this->login = $login;
		return $this;
	}

	public function getSolde()
	{
		return $this->solde;
	}

	public function setSolde($solde)
	{
		$this->solde = $solde;
		return $this;
	}

	public function getGroupes()
	{
		return $this->groupes;
	}

	public function getIdCarte()
	{
		return $this->id_carte;
	}

	public function getGroupeActif()
	{
		return $this->groupeActif;
	}

	public function setGroupeActif($groupe)
	{
		$this->groupeActif = $groupe;
	}

	public function getPromo()
	{
		return $this->promo;
	}

	public function setPromo($promo) {
		$this->promo = $promo;
		return $this;
	}

	public function getLogin()
	{
		return $this->login;
	}

	public function getNom()
	{
		return $this->nom;
	}

	public function setNom($nom) {
		$this->nom = $nom;
		return $this;
	}

	public function getPrenom()
	{
		return $this->prenom;
	}

	public function setPrenom($prenom) {
		$this->prenom = $prenom;
		return $this;
	}

	public function getPwd()			//retourne le hash du mot de passe de l'utilisateur
	{
		return $this->mdp;
	}

	public function setMdp($mdp) {
		$this->mdp = $mdp;
		return $this;
	}

	public function Authentification()
	{
		$t = new Application_Model_UsersTable();
			
		//on recupere dans la BDD la ligne si on a la bonne coresspondance login/mdp
		$rows = $t->fetchAll($t->select()->where('login = ?',$this->login)
		->where('mdp = ?',$this->mdp));
		if(count($rows) == 0 || $this->mdp = '')//si mdp vide alors pas de connexion possible, si cette ligne n'existe pas alors soit le mot de passe est mauvais soit l'utilisateur n'existe pas
		{
			return false;
		}
		else//si le mot de passe est bon alors...
		{
			$this->id_carte = $rows[0]['id_carte'];//on récupère l'id de la carte de l'user
			$t2 = new Application_Model_RolesUsersTable();
			$rows2 = $t2->fetchAll($t2->select()->where('login = ?',$this->login)->order('id_groupe'));//on récupère l'ensemble des rôles de l'user
			$last_id = -1;
			for($i = 0 ; $i < count($rows2) ; $i++)
			{
				$g = new Application_Model_Groupe();
				$g->getByID($rows2[$i]['id_groupe']);
				if($g->getID() != $last_id)
				{
					$this->groupes[] = $g;//pour chaque rôle on introduit le groupe correspondant dans la liste des groupes de l'user
					$last_id = $g->getID();
				}
			}
			$this->nom = $rows[0]['nom'];
			$this->prenom = $rows[0]['prenom'];
			$this->mdp = $rows[0]['mdp'];
			//$this->groupes = array_unique($this->groupes);
			$this->connected = true;//l'user est connecté
			return true;
		}
	}

	/**
	 *
	 * Get an Application_Model_User from its $login attribute.
	 * @param String $login
	 * @throws Zend_Exception
	 * @return The instance of Application_Model_User whose key is $login
	 */
	public static function getByLogin($login) {
		$table = self::getDbTable();
		$rows = $table->fetchAll($table->select()->where('login = ?',$login));
		//TODO: count en SQL.
		if(count($rows) == 1) {
			return self::getUserFromRow($rows[0]);
		} else {
			throw new Zend_Exception('Impossible de trouver '.$login);
		}
	}

	public function getById_Carte($id_carte)
	{
		$t=new Application_Model_UsersTable();
		$rows = $t->fetchAll($t->select()->where('id_carte = ?',$id_carte));
		if(count($rows)>0)
		{
			$this->id_carte=$id_carte;
			$this->nom=$rows[0]['nom'];
			$this->prenom=$rows[0]['prenom'];
			$this->promo=$rows[0]['promo'];
			$this->login=$rows[0]['login'];
			$this->mdp = $rows[0]['mdp'];
			$this->solde = $rows[0]['solde'];
			return $this;
		}
		else
		{
			throw new Zend_Exception("Impossible de trouver l'user.");
		}
	}



	public function getRoles()
	{
		$t=new Application_Model_RolesUsersTable();
		$rows = $t->fetchAll($t->select()->where('login = ?',$this->login));
		foreach($rows as $r)
		{
			$role=new Application_Model_Role();
			$role=$role->fromId($r['id_role']);
			$this->roles[] = $role;
		}
		$this->roles = array_unique($this->roles,SORT_REGULAR);
		return $this->roles;
	}

	public function addUser()
	{
		$table = new Application_Model_UsersTable();//on récupère la table des users
		$cartes = new Application_Model_CartesTable();
		$rows = $table->fetchAll($table->select()->where('login = ?',$this->login));
		if(count($rows) == 0)//sans ce if, une carte est créée même si l'utilisateur est déjà  dans la BDD
		{
			$id_carte =$this->NewCarte();//on crée une nouvelle carte et on récupère son id
			$data = array(
		'login' => $this->login, 
		'id_carte' => $id_carte,
		'promo' => $this->promo,
		'nom' => $this->nom,
		'prenom' => $this->prenom,
		'mdp' => $this->mdp
			);
			$table->insert($data);//on ajoute l'user dans la table
			//inscription dans l'historique
			if($this->mdp == '')
			{
				$libelle = "Ajout utilisateur sans mot de passe : ".$this->getLogin();
			}
			else
			{
				$libelle = "Ajout utilisateur avec mot de passe : ".$this->getLogin();
			}
			$histo = new Application_Model_HistoSystemElement($libelle);
			$histo->AddToHistoSystem();
			//on retourne le numéro de la nouvelle carte
			return $id_carte;
		}
		else
		{
			throw new Zend_Exception('Utilisateur déjà présent dans la base de données.');
		}
	}

	public function addRole($id_groupe,$id_role)
	{
		$data = array(
		'id_role' => $id_role,
		'login' => $this->login,
		'id_groupe' => $id_groupe
		);
		$table= new Application_Model_RolesUsersTable();
		$table->insert($data);
		//inscription dans l'historique
		$g = new Application_Model_Groupe();
		$g->getByID($id_groupe);
		$r = new Application_Model_Role();
		$r = $r->fromId($id_role);
		$libelle = "Inscription de l'user ".$this->login." dans le groupe ".$g->getName()." avec le rôle ".$r->getName();
		$histo = new Application_Model_HistoSystemElement($libelle);
		$histo->AddToHistoSystem();
	}


	public function changePwd($newpwdhash)// change le mot de passe, l'argument est le !md5! du nouveau mdp
	{
		$users= new Application_Model_UsersTable();
		$where= array('login = ?' => $this->login);
		$data = array('mdp' => $newpwdhash);
		$users->update($data,$where);
		$this->mdp = $newpwdhash;
		//inscription dans l'historique
		if($newpwdhash == NULL)
		{
			$libelle = "Suppression du mot de passe de l'user ".$this->login.".";
		}
		else
		{
			$libelle = "Changement du mot de passe de l'user ".$this->login.".";
		}
		$histo = new Application_Model_HistoSystemElement($libelle);
		$histo->AddToHistoSystem();
		return $this;
	}

	public function NewCarte()
	{
		if(isset ($this->login))
		{
			$data = array(
		'actif' => true
			);
			$table=new Application_Model_CartesTable();
			$id = $table->insert($data);
			$this->id_carte=$id;
			$libelle = "Création de la carte n°".$id;
			$histo = new Application_Model_HistoSystemElement($libelle);
			$histo->AddToHistoSystem();
			return $id;
		}
	}

	public function RechargerCarte($montant,$moyen,$renseignement=null)
	{
		$s=$this->solde+$montant;
		$where= array('login = ?' => $this->login);
		$data = array('solde'=> $s);
		$users= new Application_Model_UsersTable();
		$users->update($data,$where);
		if($moyen=='especes')
		{
			$libelle='recharge du solde de '.$this->prenom.' '.$this->nom.' promo '.$this->promo.' en espèces';
		}
		else
		{
			$libelle='recharge du solde de '.$this->prenom.' '.$this->nom.' promo '.$this->promo.' par '.$moyen.' : '.$renseignement;
		}
		$session = new Zend_Session_Namespace("codebar");
		$histo=new Application_Model_HistoCarteElement($this,$session->user,$montant,$libelle);
		$histo->save();
		$this->solde=$s;
	}

	public function getCarte()
	{
		$carte=new Application_Model_Carte();
		$carte=$carte->getById($this->id_carte);
		return $carte;
	}


	public function update()
	{
		$data = array(
		'solde' => $this->getSolde(),
		'id_carte' => $this->getIdCarte(),
		'promo' => $this->getPromo(),
		'nom' => $this->getNom(),
		'prenom' => $this->getPrenom(),
		'mdp' => $this->getPwd()
		);
		$where = array('login = ?' => $this->getLogin());
		$db = new Application_Model_UsersTable();
		$db->update($data,$where);
		return $this;
	}

	public static function triParNom($user1,$user2)
	{
		if($user1->nom<$user2->nom)
		{
			return -1;
		}
		elseif($user2->nom<$user1->nom)
		{
			return 1;
		}
		else return 0;
	}

	public function setIdCarte($id)
	{
		$this->id_carte=$id;
		return $this;
	}

	/**
	 *
	 * Search for all users with a name, surname or
	 * login corresponding to $term.
	 * @param String $term
	 * @return An array of all the corresponding users
	 */
	public static function search($term) {
		$regexp = $term;
		$regexp = '%'.$regexp.'%';
		$rows = self::getDbTable()->fetchAll(self::getDbTable()->select()
		->where('to_ascii(convert_to(nom,\'latin1\'), \'latin1\') ILIKE to_ascii(convert_to(?,\'latin1\'), \'latin1\')', $regexp)
		->orWhere('to_ascii(convert_to(prenom,\'latin1\'), \'latin1\') ILIKE to_ascii(convert_to(?,\'latin1\'), \'latin1\')', $regexp)
		->orWhere('to_ascii(convert_to(login,\'latin1\'), \'latin1\') ILIKE to_ascii(convert_to(?,\'latin1\'), \'latin1\')', $regexp)
		->order('nom'));
		$users = array();
		foreach($rows as $row) {
			$user = self::getUserFromRow($row);
			$users[] = $user;
		}
		return $users;
	}

	/**
	 *
	 * Return an instance of Application_Model_User from
	 * a row of the data base.
	 * @param unknown_type $row
	 * @return the user created from $row
	 */
	public static function getUserFromRow($row) {
		$user = new self();
		$user->setLogin($row['login'])
		->setNom($row['nom'])
		->setPrenom($row['prenom'])
		->setPromo($row['promo'])
		->setIdCarte($row['id_carte'])
		->setSolde($row['solde'])
		->setMdp($row['mdp']);
		return $user;
	}
}